﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;

namespace NodeBasedSkillEditor
{
    /// <summary>
    /// 注意，为了性能考虑，运算类方法都没有进行类型安全的检查，同时让不合理的计算行为直接报错
    /// </summary>
    public abstract class AValue
    {
        public enum EValueType
        {
            Unknown,
            Boolean,
            Integer,
            Scalar,
            Vector2,
            Vector3,
            String,
            Enum
        }

        public static AValue Factory(ValuePort portData)
        {
            if (portData is BooleanPort) return new Value_Boolean(portData as BooleanPort);
            else if (portData is IntegerPort) return new Value_Integer(portData as IntegerPort);
            else if (portData is FloatPort) return new Value_Scalar(portData as FloatPort);
            else if (portData is Vector2Port) return new Value_Vector2(portData as Vector2Port);
            else if (portData is Vector3Port) return new Value_Vector3(portData as Vector3Port);
            else if (portData is StringPort) return new Value_String(portData as StringPort);
            else if (portData is EnumPort) return new Value_Enum(portData as EnumPort);
            else return null;
        }

        public virtual EValueType ValueType { get { return EValueType.Unknown; } }

        public abstract AValue Clone();

        public bool Assign(AValue v)
        {
            switch (v.ValueType)
            {
                case EValueType.Unknown: break;
                case EValueType.Boolean: return SetBoolean((v as Value_Boolean).Value);
                case EValueType.Integer: return SetInteger((v as Value_Integer).Value);
                case EValueType.Scalar: return SetScalar((v as Value_Scalar).Value);
                case EValueType.Vector2: return SetVector2((v as Value_Vector2).Value);
                case EValueType.Vector3: return SetVector3((v as Value_Vector3).Value);
                case EValueType.String: return SetString((v as Value_String).Value);
                case EValueType.Enum: return SetEnum((v as Value_Enum).Value);
                default: break;
            }
            return false;
        }

        public virtual (bool, bool) ToBoolean() { return (false, false); }
        public virtual bool SetBoolean(bool v) { return false; }

        public virtual (bool, int) ToInteger() { return (false, 0); }
        public virtual bool SetInteger(int v) { return false; }

        public virtual (bool, float) ToScalar() { return (false, 0); }
        public virtual bool SetScalar(float v) { return false; }

        public virtual (bool, Vector2) ToVector2() { return (false, Vector2.Zero); }
        public virtual bool SetVector2(Vector2 v) { return false; }

        public virtual (bool, Vector3) ToVector3() { return (false, Vector3.Zero); }
        public virtual bool SetVector3(Vector3 v) { return false; }

        /// GetString 采用override ToString()
        public virtual bool SetString(string v) { return false; }

        public virtual (bool, Enum) ToEnum() { return (false, null); }
        public virtual bool SetEnum(Enum v) { return false; }

        public virtual void Reset() { }
        public virtual void Add(AValue x) { }
        public virtual void Subtract(AValue x) { }
        public virtual void Multiply(AValue x) { }
        public virtual void DivideBy(AValue x) { }
        public virtual void Modulo(AValue x) { }
        public virtual void Negative() { }


        public virtual void And(AValue x) { }

        public virtual void Or(AValue x) { }

        /// <summary>
        /// 异或，不同时为真
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public virtual void XOR(AValue x) { }

        /// <summary>
        /// 同或，相同时为真
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public virtual void XNOR(AValue x) { }

        public virtual bool EqualsValue(AValue x) { return false; }

    }
}
